#include "InetAddress.h"

#include <strings.h>  // bzero
#include <string>
#include <string.h>

InetAddress::InetAddress(uint16_t port, std::string ip)
{
    bzero(&addr_, sizeof(addr_));  // 缓冲区清零
    addr_.sin_family = AF_INET;  // 设置了地址族为AF_INET，这表示这是一个IPv4地址
    addr_.sin_port = htons(port);  // htons将主机字节序（可能小端）转成网络字节序（网络总是大端）
    addr_.sin_addr.s_addr = inet_addr(ip.c_str());  // inet_addr把字符串转成点分十进制的整数表示、转成网络字节序
}

// 获取Ip
std::string InetAddress::toIp() const
{
    // 从addr_中读出ip地址，但addr_里存的ip已经转成网络字节序了
    char buf[64] = {0};
    ::inet_ntop(AF_INET, &addr_.sin_addr, buf, sizeof(buf));  // 将“二进制整数” → “点分十进制”
    return buf;

}

// 获取Ip端口号
std::string InetAddress::toIpPort() const
{
    // ip:port
    char buf[64] = {0};
    ::inet_ntop(AF_INET, &addr_.sin_addr, buf, sizeof(buf));
    size_t end = strlen(buf);  // 计算点分十进制表示的ip的有效长度
    uint16_t port = ntohs(addr_.sin_port);  // ntohs将一个16位数由网络字节顺序转换为主机字节顺序
    sprintf(buf+end, ":%u", port);
    return buf;
}

// 获取端口号
uint16_t InetAddress::toPort() const
{
    return ntohs(addr_.sin_port);
}

// test
// int main()
// {
//     InetAddress addr(8080);
//     std::cout << addr.toIpPort() << std::endl;
//     std::cout << addr.toIp() << std::endl;
//     std::cout << addr.toPort() << std::endl;
//     return 0;
// }